package com.dmjj.cadcommon.okhttp;

import okhttp3.*;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName OkHttpUtils
 * @Description TODO 发起网络请求
 * @Author guozishen
 * @Date 2018/3/23 13:34
 * @Version 1.0
 **/
@Service
public class OkHttpUtils {
    private static final byte[] LOCKER = new byte[0];
    private static OkHttpUtils okHttpInstance;
    private OkHttpClient okHttpClient;

    private OkHttpUtils() {
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.readTimeout(30, TimeUnit.SECONDS);
        clientBuilder.connectTimeout(10, TimeUnit.SECONDS);
        clientBuilder.writeTimeout(60, TimeUnit.SECONDS);
        okHttpClient = clientBuilder.build();
    }

    public static OkHttpUtils getInstance(){
        if(okHttpInstance == null){
            synchronized (LOCKER){
                if(okHttpInstance == null){
                    okHttpInstance = new OkHttpUtils();
                }
            }
        }
        return okHttpInstance;
    }

    /**
     * 发起GET网络请求
     * @param reqUrl URL链接地址
     * @param headersParams 请求头参数
     * @param  params 请求参数
     * @param  object 标签
     * @author guozishen
     **/
    public Map<String, Object> sendGet(String reqUrl, Map<String, String> headersParams, Map<String, String> params, Object object){
        Map<String, Object> map = new HashMap<String, Object>();
        Request.Builder requestBuilder = new Request.Builder();
        //添加设置URL地址
        requestBuilder.url(reqUrl+setUrlParams(params));
        //添加请求头信息参数
        requestBuilder.headers(setHeaders(headersParams));
        if (null != object) {
            //添加请求标签
            requestBuilder.tag(object);
        }
        Request request = requestBuilder.build();
        String result = "";
        try {
            Response response = okHttpClient.newCall(request).execute();
            byte[] bytes = response.body().bytes();
            result = new String(bytes, "UTF-8");
            map.put("data", result);
            map.put("code", response.code());
        } catch (Exception e) {
        }
        return map;
    }

    /**
     * post 请求
     * @param reqUrl UR连接
     * @param headersParams 请求头参数
     * @param bodyParams  请求参数
     * @param object  标签
     */
    public Map<String, Object> sendPost(String reqUrl, Map<String, String> headersParams, Map<String, String> bodyParams, Object object) {
        Map<String, Object> map = new HashMap<String, Object>();
        Request.Builder RequestBuilder = new Request.Builder();
        //添加URL地址
        RequestBuilder.url(reqUrl);
        RequestBuilder.post(setRequestBody(bodyParams));
        //添加请求头
        RequestBuilder.headers(setHeaders(headersParams));
        if (null != object) {
            //添加请求标签
            RequestBuilder.tag(object);
        }
        try {
            Response response = okHttpClient.newCall(RequestBuilder.build()).execute();
            byte[] bytes = response.body().bytes();
            String result = new String(bytes, "UTF-8");
            map.put("data", result);
            map.put("code", response.code());
        } catch (Exception e) {
        }
        return map;
    }

    /**
     * post 请求
     * @param reqUrl UR连接
     * @param headersParams 请求头参数
     * @param bodyParams  请求参数(Json格式)
     * @param object  标签
     */
    public Map<String, Object> sendPostJson(String reqUrl, Map<String, String> headersParams, String bodyParams, Object object) {
        Map<String, Object> map = new HashMap<String, Object>();
        Request.Builder RequestBuilder = new Request.Builder();
        // 添加URL地址
        RequestBuilder.url(reqUrl);
        RequestBuilder.post(setRequestBodyJson(bodyParams));
        // 添加请求头
        RequestBuilder.headers(setHeaders(headersParams));
        if (null != object) {
            // 添加请求标签
            RequestBuilder.tag(object);
        }
        try {
            Response response = okHttpClient.newCall(RequestBuilder.build()).execute();
            byte[] bytes = response.body().bytes();
            String result = new String(bytes, "UTF-8");
            map.put("data", result);
            map.put("code", response.code());
        } catch (Exception e) {
        }
        return map;
    }

    /**
     * post请求参数
     * @param JsonBodyParams
     * @return
     */
    private RequestBody setRequestBodyJson(String JsonBodyParams) {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = null;
        if (JsonBodyParams != null) {
            body = RequestBody.create(JSON,JsonBodyParams);
        }
        return body;

    }

    /**
     * get方法链接的参数拼接
     * @param mapParams
     * @return
     **/
    private String setUrlParams(Map<String, String> mapParams){
        String strParams = "";
        if(mapParams != null){
            for(Map.Entry<String, String> map:mapParams.entrySet()){
                if(strParams.equals("")){
                    strParams = "?"+  map.getKey() + "=" + map.getValue();
                }else{
                    strParams += "&" + map.getKey() + "=" + map.getValue();
                }
            }
        }
        return strParams;
    }

    /**
     * post请求参数组装处理
     * @param BodyParams
     * @return
     */
    private RequestBody setRequestBody(Map<String, String> BodyParams) {
        RequestBody body = null;
        FormBody.Builder formEncodingBuilder = new FormBody.Builder();
        if (BodyParams != null) {
            for (Map.Entry<String, String> map : BodyParams.entrySet()) {
                formEncodingBuilder.add(map.getKey(), map.getValue());
            }
        }
        body = formEncodingBuilder.build();
        return body;

    }

    /**
     * 设置请求头
     * @param headersParams
     * @return
     */
    private Headers setHeaders(Map<String, String> headersParams) {
        Headers headers = null;
        Headers.Builder headersbuilder = new Headers.Builder();
        if (headersParams != null) {
            for (Map.Entry<String, String> map : headersParams.entrySet()) {
                headersbuilder.add(map.getKey(), map.getValue());
            }
        }
        headers = headersbuilder.build();
        return headers;
    }
}